#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <pthread.h>
#include <math.h>
#include "prefetch_lib.h"
#include <time.h>
#include <pthread.h>

#define FILESIZE (64 * 1024 * 1024)
#define N (FILESIZE / sizeof(int))
#define TOTALSIZE (4294967296/2)

unsigned int *mapa, *mapb, *mapc;

int fib(int n) {
  int res = 1;
  while (n > 1) {
    res *= n;
    --n;
  }
  return res;
}

int F() 
{    
    int i, j, k, s, m = 0, l;
    time_t t = time(0);
    
    for (i = 0; i < N; ++i) {
      if (i % (1024 * 4) == 0) {
        time_t n = time(0);
        if (n - t > 0) {
          printf("[%lu] in i loop; i = %d done in %lu\n", pthread_self(), i, n - t);
          t = n;
        }
      }
      s = mapb[(4096 * i) % N];
      
      
      for (l = 0; l < 1; ++l) {
        s ^= (int)(10 * sin(sin(sin(sin(cos(cos(cos(sin(s) * sin(s)))))))));
        s ^= (int)(10 * sin(sin(sin(sin(cos(cos(cos(s * sin(s)))))))));
//        s ^= (int)(10 * sin(sin(sin(sin(cos(cos(cos(s * s))))))));
      }
      
      
      m ^= mapa[s % N] /*/ mapc[i]*/;
      
      for (l = 0; l < 1; ++l) {
        m ^= (int)(10 * sin(sin(sin(sin(cos(cos(cos(sin(s) * sin(s)))))))));
        m ^= (int)(10 * sin(sin(sin(sin(cos(cos(cos(s * sin(s)))))))));
//        m ^= (int)(10 * sin(sin(sin(sin(cos(cos(cos(s * s))))))));
      }

    }

    
    return m;
}

int main(int argc, char *argv[])
{
    int f, fda, fdb, fdc;

    turn_logging(1);
    fetch_init();
    mapa = (unsigned int*)mmap(0, FILESIZE, PROT_READ, MAP_SHARED, fda = open64("a", O_RDONLY), 0);
    mapb = (unsigned int*)mmap(0, FILESIZE, PROT_READ, MAP_SHARED, fdb = open64("b", O_RDONLY), 0);
    mapc = (unsigned int*)mmap(0, FILESIZE, PROT_READ, MAP_SHARED, fdc = open64("c", O_RDONLY), 0);


    printf("a: %x-%x\n", (unsigned int)mapa >> 12, (unsigned int)(mapa + N) >> 12);    
    printf("b: %x-%x\n", (unsigned int)mapb >> 12, (unsigned int)(mapb + N) >> 12);    
    printf("c: %x-%x\n", (unsigned int)mapc >> 12, (unsigned int)(mapc + N) >> 12);    

    madvise(mapa, FILESIZE, MADV_RANDOM);
    madvise(mapb, FILESIZE, MADV_RANDOM);    
    madvise(mapc, FILESIZE, MADV_RANDOM);    

    f = F();

    munmap(mapa, FILESIZE);
    munmap(mapb, FILESIZE);
    munmap(mapc, FILESIZE);

    close(fda);
    close(fdb);
    close(fdc);

    return f;
}
